/*
 * Created by Jaren at 2021/12/29 9:32
 */

import 'dart:typed_data';

import 'package:binary/binary.dart';
import 'package:inmotion_protocol/base/vehicle_data.dart';
import 'package:inmotion_protocol/common/vehicle_info.dart';
import 'package:inmotion_protocol/lorin/bean/base/vehicle_real_time_info.dart';
import 'package:inmotion_protocol/util/byte_util.dart';

abstract class AbsAllRealTimeInfo extends AllRealTimeData {
  AbsAllRealTimeInfo(AbsRealTimeInfo realTimeInfo, AbsRealTimeState realTimeState, AbsRealTimeError realTimeError) : super(realTimeInfo, realTimeState, realTimeError);
}

abstract class AbsRealTimeInfo extends RealTimeInfo {
  final ProductProperty _property;

  Uint16 estimatedTotalMileage = Uint16.zero;
  Int8 mosTemp = Int8.zero;
  Int32 power = Int32.zero;

  /// 单次骑行时长
  Uint32 rideTime = Uint32.zero;

  /// 总里程
  Uint32 totalMileage = Uint32.zero;

  AbsRealTimeInfo(this._property) {
    estimatedTotalMileage = ByteUtil.toUint16(_property.designedRange);
  }

  AbsRealTimeInfo.fromBytes(this._property, Uint8ClampedList bytes, [int offset = 0]) {
    speed = ByteUtil.toInt16(ByteUtil.bytes2IntLe(bytes, 12, 4) ~/ 10);
    // 0.01A
    current = ByteUtil.toInt16(ByteUtil.bytes2IntLe(bytes, 20, 4));
    // 0.01V
    voltage = ByteUtil.toInt16(ByteUtil.bytes2IntLe(bytes, 24, 4));
    power = ByteUtil.toInt32((current.value * voltage.value * 0.01).toInt());
    estimatedTotalMileage = ByteUtil.toUint16(_property.designedRange);
    mosTemp = ByteUtil.toInt8(bytes[32] > bytes[33] ? bytes[32] : bytes[33]);

    totalMileage = ByteUtil.toUint32(ByteUtil.bytes2Uint32Le(bytes, 44).value ~/ 10);
  }

  @override
  int length() {
    return 0;
  }

  @override
  String toString() {
    return '${super.toString()}, AbsRealTimeInfo{speed:$speed, estimatedTotalMileage: $estimatedTotalMileage, mosTemp: $mosTemp, power: $power, rideTime: $rideTime, totalMileage: $totalMileage}';
  }
}

abstract class AbsRealTimeState extends RealTimeState {
  AbsRealTimeState.fromBytes(Uint8ClampedList bytes, [int offset = 0]);

  @override
  int length() {
    return 0;
  }
}

abstract class AbsRealTimeError extends RealTimeError {
  Uint32 originalValue = Uint32.zero;

  AbsRealTimeError.fromBytes(Uint8ClampedList bytes, [int offset = 0]);

  @override
  int length() {
    return 0;
  }
}
